/*
 * PUC-Rio - Pontificia Universidade Catolica
 *
 * Professor: Marcelo Gattass
 *
 * Arquivo: bsp.h
 *
 * Nome: Luiz Felipe Machado
 */

#ifndef BSP_H
#define BSP_H

#include <vector>

#include "triangle.h"
#include "vector.h"
#include "bbox.h"

class cNode
{
private:
public:
  int tri;

  cNode *front;
  cNode *back;

  cNode(void) : front(NULL), back(NULL) {}
};


// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class cBsp
{
private:

  /**
    * @brief Vector with vertex coordinates
    */
  std::vector<VVector> m_data_vet;

  /**
    * @brief Vector with index of coordinates of triangles.
    */
  std::vector<cTriangle> m_data_tri;

  /**
    * @brief Vector with normal vector of each triangle.
    */
  std::vector<VVector> m_data_nor;

  cNode *m_root;

  cBbox m_bbox;

  void m_draw_rec(  cNode *node, VVector &eye)  ;
  void m_draw_node(  cNode *node)  ;

  cNode* m_insert_rec(std::vector<cTriangle> &vet_tri,
                      std::vector<VVector> &vet_vertex,
                      std::vector<VVector> &vet_nor);

  int m_select_triangle(std::vector<cTriangle> &vet_tri,
                        std::vector<VVector> &vet_vertex,
                        std::vector<VVector> &vet_nor);

  void m_transf_triangle(int index_triangle,
                         std::vector<cTriangle> &vet_tri_from,
                         std::vector<VVector> &vet_vertex_from,
                         std::vector<VVector> &vet_nor_from,
                         std::vector<cTriangle> &vet_tri_to,
                         std::vector<VVector> &vet_vertex_to,
                         std::vector<VVector> &vet_nor_to);

  void m_cut_triangle(int selected_triangle, int other_triangle,
                      std::vector<cTriangle> &vet_tri,
                      std::vector<VVector> &vet_vertex,
                      std::vector<VVector> &vet_nor,
                      std::vector<cTriangle> &vet_tri_front,
                      std::vector<VVector> &vet_vertex_front,
                      std::vector<VVector> &vet_nor_front,
                      std::vector<cTriangle> &vet_tri_back,
                      std::vector<VVector> &vet_vertex_back,
                      std::vector<VVector> &vet_nor_back);

public:
  cBsp(void) : m_root(NULL) {}

  void draw(VVector &eye)  ;

  void create_bsp(std::vector<cTriangle> &vet_tri,
                  std::vector<VVector> &vet_vertex,
                  std::vector<VVector> &vet_nor);

  int get_num_triangles(void) { return (int)m_data_tri.size(); }

  void calculate_bbox(void);

  cBbox get_bbox(void) { return m_bbox; }
};

#endif // BSP_H
